home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Franz PD / Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).zip / Franz PD Disk #324 (1994-04)(Rhein-Sieg-Soft).adf / VideoText3.5 / source / s_i2cbusIO.s < prev    next >
Text File  |  1994-04-01  |  5KB  |  181 lines

  1. ;=============================================================================
  2. ; s_i2cbusIO.s: Assembler-Version der KICK-Pascal Prozedur i2cbusIO (seriell)
  3. ; Parameterübergabe (auf dem Stack):
  4. ;  12(A7).B: logische Busadresse           -> D0
  5. ;   8(A7).L: Zeiger auf den I/O-Puffer     -> A0
  6. ;   6(A7).W: Anzahl zu übertragender Daten -> D1
  7. ;   4(A7).W: Zeitschleifen-Durchgänge      -> D5
  8. ; Rückgabewert: 
  9. ;   D0.W: Status, 0 = OK, 1 = Fehler, 2 = Fehler beim Adressbyte
  10. ;-----------------------------------------------------------------------------
  11. ; Funktionsweise:
  12. ; Startet den I²C-Bus und spricht den in D0 bezeichneten Chip an. Wenn D1
  13. ; negativ ist, werden -D1 Bytes vom Bus geholt und ab Adresse A0 im Speicher 
  14. ; abgelegt, sonst +D1 Bytes ab A0 über den Bus abgeschickt. Die Busadresse 
  15. ; (D0) wird dabei automatisch zur Schreib- bzw. Leseadresse gemäß I²C-Bus-
  16. ; Konvention korrigiert. Abschließend wird der I²C-Bus wieder gestoppt.
  17. ; Anmerkungen:
  18. ; 1. Die über D5 bestimmte Zeitschleife soll den Bustakt bremsen, wobei
  19. ;    maximal 100 kHz zulässig sind, "zu langsam" gibt es dagegen am I²C-Bus 
  20. ;    NICHT. Auf normalen Amigas sollte D5=0 sein.
  21. ; 2. Mehr Bytes zum Lesen anzufordern, als der bereitgestellte Puffer fassen
  22. ;    kann, ist ein Fehler, der nicht erkannt werden kann und wahrscheinlich
  23. ;    mit einem GURU endet.
  24. ;=============================================================================
  25.  
  26. ; interne Registerverwendung:
  27. ; D0: Datenbyte, das gesendet oder empfangen wird
  28. ; D1: Anzahl zu übertragende Bytes
  29. ; D2: Zähler über gesendete Bytes
  30. ; D3: Zähler über 8 Bits
  31. ; D4: Zähler für Zeitschleife
  32. ; D5: Grenze für Zeitschleife
  33. ; A0: Pufferzeiger
  34. ; A1: Adresse des CIA-Ports
  35.  
  36. CIABPRA  = $BFD000
  37. CIABDDRA = $BFD200
  38. ClkOutBit  = 6 ; CIAB_COMRTS
  39. ClkInBit   = 4 ; CIAB_COMCTS
  40. DataOutBit = 7 ; CIAB_COMDTR
  41. DataInBit  = 5 ; CIAB_COMCD
  42.  
  43. DELAY MACRO
  44.   move.w d5,d4
  45. loop\@ dbf d4,loop\@
  46.   ENDM
  47.  
  48. ; Linker-Information:
  49.   xdef s_i2cbusIO
  50.  
  51. s_i2cbusIO:
  52. ; Parameter vom Stack holen:
  53.   move.b 12(a7),d0
  54.   move.l 8(a7),a0
  55.   move.w 6(a7),d1
  56.   move.w 4(a7),a1
  57.  
  58. test:
  59. ; veränderte Register retten: D2,D3,D4,D5
  60.   movem.l d2-d5,-(a7)
  61.  
  62. ; einen der Parameter noch ins richtige Register packen:
  63.   move.w a1,d5
  64.  
  65. ; CIA-Datenrichtungsregister initialisieren
  66.   move.l #CIABDDRA,a1
  67.   bset #ClkOutBit,(a1)
  68.   bset #DataOutBit,(a1)
  69.   bclr #ClkInBit,(a1)
  70.   bclr #DataInBit,(a1)
  71.  
  72. ; Bus in Ruhezustand bringen: DATA=HI, CLK=HI
  73.   move.l #CIABPRA,a1
  74.   bset #DataOutBit,(a1)
  75.   bset #ClkOutBit,(a1)
  76.   
  77. ; Bus starten (Protokollverletzung H->L): DATA=LO, CLK=LO
  78.   DELAY
  79.   bclr #DataOutBit,(a1)
  80.   DELAY
  81.   bclr #ClkOutBit,(a1)
  82.   DELAY
  83.  
  84. ; Soll ich senden oder empfangen?
  85.   bclr #0,d0 ; Voreinstellung: Adresse als Sendeadresse
  86.   tst.w d1
  87.   bpl .zweck
  88.     bset #0,d0   ; Adresse als Leseadresse
  89. .zweck:
  90.  
  91. ; Daten senden, mindestens die Adresse, und evtl. <D1> weitere Bytes
  92. ; (Adressbyte steht bereits in D0):
  93.   clr.w d2 ; Bytezähler auf Null
  94. SendLoop: ; das in D0 enthaltene Byte über den Bus schicken, MSB zuerst
  95.   moveq.b #7,d3
  96. SBitLoop:
  97.   btst d3,d0
  98.   beq .SL1
  99.   bset #DataOutBit,(a1) ; "1" senden
  100.   bra .SL2
  101. .SL1 bclr #DataOutBit,(a1) ; "0" senden
  102. .SL2: ; Einen CLK-Impuls geben, um das Bit lesen zu lassen
  103.   bset #ClkOutBit,(a1)
  104.   DELAY
  105.   bclr #ClkOutBit,(a1)
  106.   DELAY
  107.   dbf d3,SBitLoop
  108. ; 9. CLK-Impuls, um Quittungsbit zu lesen:
  109.   bset #DataOutBit,(a1) ; sonst liest man nur das eigene LO!
  110.   bset #ClkOutBit,(a1)
  111.   DELAY
  112.   btst #DataInBit,(a1)
  113.   bne SendErr ; DATA=HI -> NAK, Übertragung abbrechen
  114.   bclr #ClkOutBit,(a1)
  115.   DELAY
  116. ; genug Daten gesendet?
  117.   addq.w #1,d2 ; gesendetes Byte zählen
  118.   cmp.w d1,d2 ; dran denken: Adressbyte wurde mitgezählt
  119.   bgt SendEnd ; ja, fertig (schließt auch den Fall d1<0 ein)
  120.   move.b (a0)+,d0 ; nein, Byte aus Puffer holen
  121.   bra SendLoop
  122. SendErr:
  123.   moveq.w #1,d0 ; Status = unquittiertes Byte
  124.   tst.w d2 ; das wievielte Byte war es?
  125.   bne BusStop ; irgendeins
  126.   moveq.w #2,d0 ; sonst: Status = unquittiertes Adressbyte
  127.   bra BusStop  
  128. SendEnd:
  129.   tst.w d1
  130.   bmi RecvLoop ; es sollen auch noch Bytes empfangen werden
  131.   moveq.w #0,d0 ; Status = OK
  132.   bra BusStop
  133.   
  134. ; soviele Bytes empfangen, wie in A1 angegeben:
  135. RecvLoop: ; ein Byte vom Bus holen, MSB zuerst, und in D0 zusammensetzen
  136.   bset #DataOutBit,(a1) ; DATA-Leitung freigeben
  137.   clr.b d0
  138.   moveq.b #7,d3
  139. RBitLoop:
  140. ; Einen CLK-Impuls geben, ein Bit lesen:
  141.   bset #ClkOutBit,(a1)
  142.   DELAY
  143.   btst #DataInBit,(a1)
  144.   beq .RL1 ; "0" empfangen, nichts tun
  145.   bset d3,d0 ; "1" empfangen, entsprechendes Bit setzen
  146. .RL1 bclr #ClkOutBit,(a1)
  147.   DELAY
  148.   dbf d3,RBitLoop
  149.   move.b d0,(a0)+ ; Byte im Puffer speichern
  150. ; Quittierungsbit senden, "0", außer nach dem letzten Byte:
  151.   addq.w #1,d1 ; empfangenes Byte zählen
  152.   beq .RL2 ; letztes Byte, DATA auf HI lassen
  153.   bclr #DataOutBit,(a1) ; nein, DATA=LO
  154. .RL2: ; CLK-Impuls geben, Quittungsbit lesen lassen:
  155.   bset #ClkOutBit,(a1)
  156.   DELAY
  157.   bclr #ClkOutBit,(a1)
  158.   DELAY
  159. ; alle Daten empfangen?
  160.   tst.w d1
  161.   bne RecvLoop ; nein, weitermachen
  162.   moveq.w #0,d0 ; Status: OK
  163.  
  164. BusStop: ; I²C-Bus stoppen (Protokollverletzung L->H): CLK=HI, DATA=HI
  165. ; zunächst noch CLK=LO, DATA=LO sicherstellen:
  166.   bclr #ClkOutBit,(a1)
  167.   bclr #DataOutBit,(a1)
  168.   
  169.   DELAY
  170.   bset #ClkOutBit,(a1)
  171.   DELAY
  172.   bset #DataOutBit,(a1)
  173.   DELAY
  174.   
  175. ; gerettete Register zurückholen: D2,D3,D4,D5
  176.   movem.l (a7)+,d2-d5
  177.   rts
  178.  
  179.   end
  180.   
  181.